package com.signway.swmediaplayerdemo;

import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;

public class FpsMonitor {
    public static final String TAG = FpsMonitor.class.getName();
    private static final long SECOND_IN_NANOS = 1000_000000L;
    private static final long UPDATE_FPS_DURATION_NANOS = SECOND_IN_NANOS;

    private static volatile FpsMonitor instance = null;

    public static FpsMonitor get() {
        if (instance == null) {
            synchronized (FpsMonitor.class) {
                if (instance == null) {
                    instance = new FpsMonitor();
                }
            }
        }
        return instance;
    }

    private long lastFPSUpdateNanos = 0L;
    private final ArrayList2<Long> frameTimeNanoList = new ArrayList2<>(100);

    public void updateFPS(long frameTimeNanos) {
        if (frameTimeNanos > 0) {
            frameTimeNanoList.add(frameTimeNanos);
            if (lastFPSUpdateNanos == 0) {
                lastFPSUpdateNanos = frameTimeNanoList.get(0);
            }
            if (frameTimeNanos - lastFPSUpdateNanos > UPDATE_FPS_DURATION_NANOS) {
                deleteSmallerThan(frameTimeNanoList, frameTimeNanos - SECOND_IN_NANOS);
                int size = frameTimeNanoList.size();
                if (size > 1) {
                    long durationNanos = (frameTimeNanoList.get(size - 1) - frameTimeNanoList.get(0)) / (size - 1);
                    float fps = (float) (SECOND_IN_NANOS * 1.0 / durationNanos);
                    Log.i(TAG, "ui fps " + String.format("%.2f", fps));
                }
                lastFPSUpdateNanos = frameTimeNanos;
            }
        }
    }

    private static class ArrayList2<E> extends ArrayList<E> {

        public ArrayList2(int initialCapacity) {
            super(initialCapacity);
        }

        @Override
        public void removeRange(int fromIndex, int toIndex) {
            super.removeRange(fromIndex, toIndex);
        }
    }

    private static void deleteSmallerThan(ArrayList2<Long> list, long val) {
        int index = Collections.binarySearch(list, val);
        if (index < 0) {
            index = Math.min(-index - 1, list.size() - 1);
        }
        list.removeRange(0, index);
    }

}
